package com.business.app.wechat.core.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.business.app.wechat.core.entity.UserInfoEntity;
import com.business.app.wechat.core.url.UrlEnum;
import com.business.app.wechat.core.util.HttpRequest;
import com.business.app.wechat.core.entity.WeChatConstant;
import com.business.app.wechat.core.entity.WeChatEnum;
import com.business.app.wechat.core.service.WeChatCoreService;
import org.jeecg.common.util.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

/**
 * TODO:关于使用redis管理access_token 和 jsApi_ticket的部分,需要重新设计分析
 *
 * @author gchiaway
 * 日期: 2020-04-04
 * 时间: 23:39
 */
@Service("weChatCoreService")
@Transactional
public class WeChatCoreServiceImpl implements WeChatCoreService {
    private static final Logger logger = LoggerFactory.getLogger(WeChatCoreServiceImpl.class);

    /**
     * 微信相关常量
     */
    private final WeChatConstant constant;

    /**
     * 缓存管理
     */
    private final RedisUtil redisUtil;

    @Autowired
    public WeChatCoreServiceImpl(WeChatConstant weChatConstant,
                                 RedisUtil redisUtil) {
        this.constant = weChatConstant;
        this.redisUtil = redisUtil;
        if (StringUtils.isEmpty(redisUtil.get(WeChatEnum.ACCESSTOKEN.getKey())) || StringUtils.isEmpty(redisUtil.get(WeChatEnum.JSAPITICKET.getKey()))) {
            this.updateTokenAndTicket();
        }
    }

    /**
     * 更新access_token 和 jsApi_ticket
     *
     * @return 是否成功
     */
    @Override
    public Boolean updateTokenAndTicket() {
        redisUtil.set(WeChatEnum.ACCESSTOKEN.getKey(), this.getAccessToken());
        redisUtil.set(WeChatEnum.JSAPITICKET.getKey(), this.getJsApiTicket());
        return true;
    }

    /**
     * 获取基础接口access_token
     *
     * @return access_token
     */
    @Override
    public String getAccessToken() {
        String requestUrl = UrlEnum.GET_ACCESS_TOKEN.getUrl()
                .replace("APPID", constant.getAPPID())
                .replace("APPSECRET", constant.getAPPSECRET());
        String stringResult;
        try {
            stringResult = HttpRequest.sendGet(requestUrl);
        } catch (Exception e) {
            logger.error("获取token失败 {}", e);
            return "";
        }
        if (StringUtils.isEmpty(stringResult)) {
            logger.info("获取token失败，微信服务器无响应");
            return "";
        }
        // 如果请求成功
        JSONObject result = JSONObject.parseObject(stringResult);
        if (!StringUtils.isEmpty(result.getString("errcode"))) {
            logger.info("获取token失败，错误码:" + result.getString("errcode") + ", 错误信息:" + result.getString("errmsg"));
            return "";
        }
        return result.getString("access_token");
    }

    /**
     * 获取jsApi_ticket
     *
     * @return jsApi_ticket
     */
    @Override
    public String getJsApiTicket() {
        String accessToken = String.valueOf(redisUtil.get(WeChatEnum.ACCESSTOKEN.getKey()));
        if (StringUtils.isEmpty(accessToken)) {
            logger.info("获取ticket失败，accessToken为空");
            return "";
        }
        String requestUrl = UrlEnum.GET_JsAPI_TICKET.getUrl()
                .replace("ACCESS_TOKEN", accessToken);
        String stringResult;
        try {
            stringResult = HttpRequest.sendGet(requestUrl);
        } catch (Exception e) {
            logger.info("获取ticket失败 {}", e);
            return "";
        }
        if (StringUtils.isEmpty(stringResult)) {
            logger.info("获取ticket失败，微信服务器无响应");
            return "";
        }
        // 如果请求成功
        JSONObject result = JSONObject.parseObject(stringResult);
        if (StringUtils.isEmpty(result.getString("errcode")) || !"0".equals(result.getString("errcode"))) {
            logger.info("获取ticket失败，错误码:" + result.getString("errcode") + ", 错误信息:" + result.getString("errmsg"));
            return "";
        }
        return result.getString("ticket");
    }


    /**
     * 通过网页授权获取openId
     *
     * @param code 微信code
     * @return openId
     */
    @Override
    public String getOpenId(String code) {
        String requestUrl = UrlEnum.GET_OPENID.getUrl()
                .replace("APPID", constant.getAPPID())
                .replace("APPSECRET", constant.getAPPSECRET())
                .replace("CODE", code);
        String stringResult;
        try {
            stringResult = HttpRequest.sendGet(requestUrl);
        } catch (Exception e) {
            logger.error("获取openid失败 {}", e);
            return "";
        }
        if (StringUtils.isEmpty(stringResult)) {
            logger.info("获取openid失败，微信服务器无响应");
            return "";
        }
        // 如果请求成功
        JSONObject result = JSONObject.parseObject(stringResult);
        if (!StringUtils.isEmpty(result.getString("errcode"))) {
            logger.info("获取openid失败，错误码:" + result.getString("errcode") + ", 错误信息:" + result.getString("errmsg"));
            return "";
        }
        return result.getString("openid");
    }

    /**
     * 通过openId获取用户信息
     *
     * @param openId openId
     * @return 用户信息
     */
    @Override
    public UserInfoEntity getUserInfo(String openId) {
        String accessToken = String.valueOf(redisUtil.get(WeChatEnum.ACCESSTOKEN.getKey()));
        if (StringUtils.isEmpty(accessToken)) {
            logger.info("获取用户信息失败，accessToken为空");
            return null;
        }
        String requestUrl = UrlEnum.GET_USER_INFO.getUrl()
                .replace("ACCESS_TOKEN", accessToken)
                .replace("OPENID", openId);
        String stringResult;
        try {
            stringResult = HttpRequest.sendGet(requestUrl);
        } catch (Exception e) {
            logger.error("获取用户信息失败 {}", e);
            return null;
        }
        if (StringUtils.isEmpty(stringResult)) {
            logger.info("获取用户信息失败，微信服务器无响应");
            return null;
        }
        // 如果请求成功
        JSONObject result = JSONObject.parseObject(stringResult);
        if (!StringUtils.isEmpty(result.getString("errcode"))) {
            logger.info("获取用户信息失败，错误码:" + result.getString("errcode") + ", 错误信息:" + result.getString("errmsg"));
            return null;
        }
        UserInfoEntity userInfo = new UserInfoEntity();
        userInfo.setHeadImgUrl(result.getString("headimgurl"));
        userInfo.setOpenId(result.getString("openid"));
        userInfo.setNickname(result.getString("nickname"));
        userInfo.setSex(result.getInteger("sex"));
        return userInfo;
    }
}
